﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using DigitalRune.Windows.TextEditor;
using DigitalRune.Windows.TextEditor.Document;
using DigitalRune.Windows.TextEditor.Formatting;
using DigitalRune.Windows.TextEditor.Highlighting;
using DigitalRune.Windows.TextEditor.Selection;
using ICSharpCode.HtmlSyntaxColorizer;
using WeifenLuo.WinFormsUI.Docking;

namespace Zove.Desktop {
    public class AbstractDesktopForm : Form, IDesktopForm {

        #region IDesktopForm Members

        public virtual void Execute() {
        }

        public virtual TextEditorControl GetTextEditorControl() {
            return null;
        }

        public string SelectedText {
            get {
                return this.GetTextEditorControl().ActiveTextAreaControl.TextArea.SelectionManager.SelectedText;
            }
        }

        public List<ISelection> Selections {
            get {
                return this.GetTextEditorControl().ActiveTextAreaControl.TextArea.SelectionManager.Selections;
            }
        }

        public virtual string GetFileExtension() {
            return string.Empty;
        }

        public virtual void InitializeComponent() {
        }

        public AbstractDesktopForm() {
            InitializeComponent();

            this.TextChanged += new EventHandler(Form_TextChanged);
            if (this.GetTextEditorControl() != null) {
                this.GetTextEditorControl().ContextMenu = new ContextMenu();
                this.GetTextEditorControl().DocumentChanged
                    += new EventHandler<DocumentEventArgs>(
                    DocumentChanged);
                this.GetTextEditorControl().Document.HighlightingStrategy
                    = HighlightingManager.Manager.FindHighlighter("Zoom");
                this.GetTextEditorControl().Document.FormattingStrategy
                    = new CSharpFormattingStrategy();
                this.GetTextEditorControl().Document.FoldingManager.FoldingStrategy
                    = new CodeFoldingStrategy();
                this.FormClosing
                    += new FormClosingEventHandler(EditingForm_FormClosing);
                this.GetTextEditorControl().Font = DesktopFormContext.Context.Font;
                this.GetTextEditorControl().ActiveTextAreaControl.TextEditorProperties.ShowLineNumbers = DesktopFormContext.Context.ShowLineNumber;
            }
            this.IsDirty = false;
        }

        public string Source {
            get {
                return this.GetTextEditorControl().Text;
            }
            set {
                this.GetTextEditorControl().Text = value;
            }
        }

        public string GetFileName() {
            return this.FileName;
        }
          
        public bool IsDirty {
            get;
            set;
        }

        public void Form_TextChanged(object sender, EventArgs e) {
            //foreach(string key in DesktopFormContext.Context.Keys) {
            //    Form f = DesktopFormContext.Context[key];
            //    if (f == this) {
            //        string x = key.Split(' ')[0];
            //        DesktopFormContext.Context.Add(x + " " + f.Text, f);
            //        DesktopFormContext.Context.Remove(key);
            //        return;
            //    }
            //}
        }

        private bool firstTimeLoading = true;

        public void DocumentChanged(object sender, DocumentEventArgs e) {
            if (!IsDirty) {
                this.Text = this.Text + "*";
                IsDirty = true;
            }
        }

        public virtual void Save(string fileName) {
            if (fileName.EndsWith(this.GetFileExtension())) {
                File.WriteAllText(fileName, Source);

                this.FileName = fileName;
                this.Text = fileName;

                this.IsDirty = false;
            } else if (fileName.EndsWith(".html")) {
                HtmlWriter w = new HtmlWriter();
                w.ShowLineNumbers = true;
                w.AlternateLineBackground = true;
                string html = w.GenerateHtml(
                    this.GetTextEditorControl().Text, this.GetColouringScheme());

                File.WriteAllText(fileName,
                    "<html><body>" + html + "</body></html>");
            }
        }

        public virtual string GetFileFilter() {
            return string.Empty;
        }

        public void OnKeyDown(object sender, KeyEventArgs e) {
            if (e.Control && (e.KeyCode == System.Windows.Forms.Keys.A)) {
                //this.GetTextEditorControl().Document.te.SelectAll();
                e.Handled = true;
            }
        }

        public Font Font {
            get {
                return this.GetTextEditorControl().ActiveTextAreaControl.TextEditorProperties.Font;
            }
            set {
                this.GetTextEditorControl().ActiveTextAreaControl.TextEditorProperties.Font = value;
            }
        }

        public bool LineNumberVisible {
            get {
                return this.GetTextEditorControl().ActiveTextAreaControl.TextEditorProperties.ShowLineNumbers;
            }
            set {
                this.GetTextEditorControl().ActiveTextAreaControl.TextEditorProperties.ShowLineNumbers = value;
            }
        }

        public int CurrentLine {
            set {
                this.GetTextEditorControl().ActiveTextAreaControl.JumpTo(value);
            }
            get {
                return this.GetTextEditorControl().ActiveTextAreaControl.Caret.Line;
            }
        }

        public int CurrentColumn {
            set {
                this.GetTextEditorControl().ActiveTextAreaControl.Caret.Column = value;
            }
            get {
                return this.GetTextEditorControl().ActiveTextAreaControl.Caret.Column;
            }
        }

        public string FileName {
            get;
            set;
        }

        public void EditingForm_FormClosing(object sender, FormClosingEventArgs e) {
            if (IsDirty) {
                switch (MessageBox.Show(
                    "The file was changed, do you want to save it?",
                    "", MessageBoxButtons.YesNoCancel)) {
                    case DialogResult.Yes:
                        if (string.IsNullOrEmpty(FileName)) {
                            SaveFileDialog dialog = new SaveFileDialog();
                            if (dialog.ShowDialog() == DialogResult.OK) {
                                FileName = dialog.FileName;
                                this.GetTextEditorControl().SaveFile(FileName);
                            }
                        }
                        break;
                    case DialogResult.No:
                        break;
                    case DialogResult.Cancel:
                        e.Cancel = true;
                        break;
                    default:
                        break;
                }
            }
        }

        public virtual string GetColouringScheme() {
            return string.Empty;
        }

        #endregion
    }
}
